package dbops

import (
	"database/sql"
	"log"
	"strconv"
	"sync"
	"video_server/api/defs"
)

// db与session的交互逻辑

// 写入session
func SaveSessionToDB(sid string, ttl int64, username string) error {
	ttlstr := strconv.FormatInt(ttl, 10)
	stmtIns, err := dbConn.Prepare("INSERT INTO sessions (session_id, TTL, login_name) VALUES (?, ?, ?)")
	if err != nil {
		return err
	}

	_, err = stmtIns.Exec(sid, ttlstr, username)
	if err != nil {
		return err
	}
	defer stmtIns.Close()
	return nil
}

func RetrieveSession(sid string) (*defs.SimpleSession, error) {
	ss := &defs.SimpleSession{}
	stmtOut, err := dbConn.Prepare("SELECT session_id, TTL, login_name FROM sessions WHERE session_id = ?")
	if err != nil {
		return nil, err
	}
	defer stmtOut.Close()

	var ttl string
	var username string
	err = stmtOut.QueryRow(sid).Scan(&ttl, &username)
	if err != nil && err != sql.ErrNoRows {
		return nil, err
	}

	if res, err := strconv.ParseInt(ttl, 10, 64); err == nil {
		ss.TTL = res
		ss.Username = username
	} else {
		return nil, err
	}

	defer stmtOut.Close()
	return ss, nil
}

func RetrieveAllSessions() (*sync.Map, error) {
	sessions := &sync.Map{}
	stmtOut, err := dbConn.Prepare("SELECT session_id, TTL, login_name FROM sessions")
	if err != nil {
		log.Printf("Error: %s", err)
		return nil, err
	}
	defer stmtOut.Close()

	rows, err := stmtOut.Query()
	if err != nil {
		log.Printf("Error: %s", err)
		return nil, err
	}
	defer rows.Close()

	for rows.Next() {
		var sessionID, ttl, loginName string
		if err := rows.Scan(&sessionID, &ttl, &loginName); err != nil {
			return nil, err
		}
		if ttl, err1 := strconv.ParseInt(ttl, 10, 64); err1 == nil {
			ss := &defs.SimpleSession{Username: loginName, TTL: ttl}
			sessions.Store(sessionID, ss)
		}
	}
	return sessions, nil
}

func DeleteSession(sid string) error {
	stmtDel, err := dbConn.Prepare("DELETE FROM sessions WHERE session_id = ?")
	if err != nil {
		return err
	}
	_, err = stmtDel.Exec(sid)
	if err != nil {
		return err
	}
	defer stmtDel.Close()
	return nil
}
